package com.lmxdawn.api.dnf.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.lmxdawn.api.common.res.BaseResponse;
import com.lmxdawn.api.common.util.ResultVOUtils;
import com.lmxdawn.api.dnf.annotation.LoginIgnore;
import com.lmxdawn.api.dnf.dto.WxpayConfig;
import com.lmxdawn.api.dnf.entity.Order;
import com.lmxdawn.api.dnf.service.OrderService;
import com.lmxdawn.api.dnf.service.WxPayService;
import com.lmxdawn.api.dnf.config.MQConfig;
import com.lmxdawn.api.dnf.dto.CommonReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/web/dnf/mall/payment/wxpay")
@Slf4j
public class WxPayController {

    @Resource
    WxpayConfig wxpayConfig;
    @Resource
    OrderService orderService;
    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 查询微信订单
     *
     * @param orderId
     * @return
     */
    @GetMapping("/query/{orderId}")
    public BaseResponse queryOrder(@PathVariable String orderId) {
        Map map = wxPayService.queryOrder(orderId);
        return ResultVOUtils.success(map);
    }


    /**
     * 关闭微信订单
     *
     * @param orderId
     * @return
     */
    @PutMapping("/close/{orderId}")
    public BaseResponse closeOrder(@PathVariable String orderId) {
        Map map = wxPayService.closeOrder(orderId);
        return ResultVOUtils.success(map);
    }

    /**
     * 下单
     *
     * @param req
     * @return
     */
    @PostMapping("/nativePay")
    public BaseResponse nativePay(@RequestBody CommonReq<Map> req) throws Exception {
        //, @RequestParam("money") String money
//        var content = req.getContent();
//        var orderId = MapUtil.getStr(content, "orderId");
//        Map map = wxPayService.nativePay(orderId);
//        //设置订单支付时间,将消息发送至mq,使用mq的死信队列
//        rabbitTemplate.convertAndSend("", MQConfig.ORDER_CREATE_QUEUE,orderId);
//        log.info("send to {}, msg:{}", MQConfig.ORDER_CREATE_QUEUE, orderId);
//        return ResultVOUtils.success(map);
        throw new RuntimeException("微信支付暂无法使用，当前仅支持支付宝付款");
//        var content = req.getContent();
//        var orderId = MapUtil.getStr(content, "orderId");
//        Map map = wxPayService.nativePay(orderId);
//        //设置订单支付时间,将消息发送至mq,使用mq的死信队列
//        rabbitTemplate.convertAndSend("", MQConfig.ORDER_CREATE_QUEUE,orderId);
//        return ResultVOUtils.success(map);
    }

    @RequestMapping("/notify")
    @LoginIgnore
    public void notifyLogic(HttpServletRequest request, HttpServletResponse response) {
        try {
            //输入流转换为字符串
            String json = convertToString(request.getInputStream());
            log.info("微信支付成功回调,入参：{}", json);
            //基于微信发送的通知内容,完成后续的业务逻辑处理
            JSONObject map = JSON.parseObject(json);
            if ("TRANSACTION.SUCCESS".equals(map.getString("event_type"))) {
                //查询订单
                JSONObject resource = map.getJSONObject("resource");
                String associatedData = resource.getString("associated_data");
                String nonce = resource.getString("nonce");
                String ciphertext = resource.getString("ciphertext");
                log.info("pay {},{},{}", associatedData, nonce, ciphertext);
                String decrypted = wxpayConfig.getAesUtil().decryptToString(associatedData.getBytes(),
                        nonce.getBytes(), ciphertext);
                JSONObject orderDetail = JSON.parseObject(decrypted);
                if ("SUCCESS".equals(orderDetail.getString("trade_state"))) {
                    Map message = new HashMap();
                    message.put("orderId", orderDetail.get("out_trade_no"));
                    message.put("transactionId", orderDetail.get("transaction_id"));
                    rabbitTemplate.convertAndSend("", MQConfig.ORDER_PAY, JSON.toJSONString(message));

                } else {
                    log.error("支付失败：{}", decrypted);
                }

            } else if("REFUND.SUCCESS".equals(map.getString("event_type"))){
                JSONObject resource = map.getJSONObject("resource");
                String associatedData = resource.getString("associated_data");
                String nonce = resource.getString("nonce");
                String ciphertext = resource.getString("ciphertext");
                log.info("pay {},{},{}", associatedData, nonce, ciphertext);
                String decrypted = wxpayConfig.getAesUtil().decryptToString(associatedData.getBytes(),
                        nonce.getBytes(), ciphertext);
                JSONObject orderDetail = JSON.parseObject(decrypted);
                if ("SUCCESS".equals(orderDetail.getString("refund_status"))) {
                    String transactionId = orderDetail.getString("transaction_id");
                    orderService.lambdaUpdate().eq(Order::getTransactionId, transactionId)
                            .set(Order::getPaymentStatus, 3).update();
                } else {
                    log.error("支付失败：{}", decrypted);
                }
            }else{
                //输出错误原因
                log.error("微信支付失败，失败信息：{}", map.get("err_code_des"));
            }


            //给微信一个结果通知
            response.setContentType("text/xml");
            String data = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            response.getWriter().write(data);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws GeneralSecurityException, IOException {
        String s = "nSFbn+BjMaVVRQRv7NjG1xhhxaXsbUaM3KnY6aIsvl1QtI+11dq/xtR/4J2N/Bx/rihVPLY5J/WhkZH1YelUpO11G+u50l1XztPd5wynPpH55k2C86TL5Ebx6cpLtquaHkqXO9/qSWsC1c+ENr4rqgxFvl99eeDAO4nRFeiX+1cOrm/GUX+NaSA01Q2mLScfQ5VSHsyLEhrASN5b4rAN4O8kprfkoNnPWAF4LBWN2btWg3BkhR+qNvxgW0gJCVmxTQqdD/Bas9+8WmJFH6zkfY60rjm1BiO3JnK560jgCvA4IAVccAr9Cf1zGYvcR9BpKhyUgJGmOh/WKxuTT5u4hhD3Pj2lj3wFqUnprSG929YmAELWT0mQr/wW7a5JBoxxfoDpMJYeZfeiXaHflyuCC9MIaVUcgUg/JvMa9JvVGpkOPKNjDSYpsednFqFf/21mIkoZ00rPsoBbJKOK8tcRA5ZqFHiFEYEk8ssZs6x/PyVKlUei8IgN6jv5VK9hkKnm1+xtx61SXLKtkVmYRoNSCZs=";
        System.out.println(new WxpayConfig().getAesUtil().decryptToString("refund".getBytes(), "nFTRfBaFxH7e".getBytes(), s));
    }
    /**
     * 输入流转换为xml字符串
     *
     * @param inputStream
     * @return
     */
    private String convertToString(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inputStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inputStream.close();
        String result = new String(outSteam.toByteArray(), "utf-8");
        return result;
    }
}
